#include <stdlib.h>
#include <cstring>
#include <cstdarg>
#include "vl_buffer.h"

using namespace VL;

extern "C" {
	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 19:32:34
	 * 
	 * float 组装结构体
	 */
	union _vl_buffer_float {
		float number;
		char c[4];
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 19:32:34
	 * 
	 * double 组装结构体
	 */
	union _vl_buffer_double {
		double number;
		char c[8];
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 19:31:52
	 * 
	 * 大端字节序检查联合体
	 */
	union _vl_buffer_byteorder_checker {
		uint16_t number = 0x1234;
		char c[2];
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-19 19:12:47
	 * 
	 * 判断当前是否为大端字节序
	 * 
	 * @return 如果是大端字节序返回 true
	 */
	bool _vl_buffer_check_is_big_order() {
		_vl_buffer_byteorder_checker checker;
		return (checker.c[0] & 0xFF) == 0x12;
	}

}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:50:20
 * 
 * 构造方法
 * @param msg 异常消息
 */
VLBufferException::VLBufferException(std::string msg): message(msg) {
	
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:51:01
 * 
 * 获取异常消息
 */
std::string VLBufferException::getMessage() const {
	return this->message;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:14:06
 * 
 * 构造函数，初始化缓冲长度
 * @param initSize 初始化缓冲长度
 */
Buffer::Buffer(uint32_t initSize) {
	this->buffer = new uint8_t[initSize];
	this->readIdx = 0;
	this->bufferLength = 0;
	this->totalLength = initSize;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:21:04
 * 
 * 析构函数
 * 回收缓冲资源
 */
Buffer::~Buffer() {
	delete buffer;
}



/**
 * @Author: CimZzz
 * @Date: 2022-07-29 11:39:07
 * 
 * 获取可读取缓存长度
 * @return 可读取缓存长度
 */
uint32_t Buffer::getReadableLength() const {
	return this->bufferLength - this->readIdx;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 17:02:46
 * 
 * 获取当前缓冲长度
 * @return 缓冲长度
 */
uint32_t Buffer::getBufferLength() const {
	return this->bufferLength;
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:57:05
 * 
 * 获取当前缓冲区已申请的内存长度
 * @return 已申请的内存长度
 */
uint32_t Buffer::getTotalLength() const {
	return this->totalLength;
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-10 17:06:07
 * 
 * 重置当前内存缓冲区
 */
void Buffer::reset() {
	this->readIdx = 0;
	this->bufferLength = 0;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:29:07
 * 
 * 复制字节到当前缓冲区中
 * @param buffer 字节数组指针
 * @param offset 偏移位置
 * @param length 复制长度
 */
void Buffer::appendBuffer(const uint8_t* buffer, uint32_t offset, uint32_t length) {
	this->_appendBuffer(this->bufferLength, buffer, offset, length);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:29:07
 * 
 * 复制字节到当前缓冲区中
 * @param buffer 字节缓冲区
 * @param offset 偏移位置
 * @param length 复制长度，0 表示复制到末尾
 */
void Buffer::appendBuffer(const Buffer* buffer, uint32_t offset, uint32_t length) {
	if(offset >= buffer->bufferLength) {
		throw std::string("Not enough bytes can be copied!");
	}


	uint32_t realLength = 0;
	if(length != 0) {
		if(offset + length > buffer->bufferLength) {
			throw std::string("Not enough bytes can be copied!");
		}
		realLength = length;
	} else {
		realLength = buffer->bufferLength - offset;
	}

	this->appendBuffer(buffer->buffer, offset, realLength);
}


/**
 * @Author: CimZzz
 * @Date: 2022-02-15 18:05:52
 * 
 * 复制字符串到当前缓冲区中
 * @param str 字符串
 */
void Buffer::appendStrBuffer(const char * str) {
	size_t strLength = std::strlen(str);
	if(strLength <= 0) {
		return;
	}

	this->appendBuffer((uint8_t *)str, 0, strLength);
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:44:31
 * 
 * 复制字符串到当前缓冲区中
 * @param str 字符串
 */
void Buffer::appendStrBuffer(const std::string& str) {
	this->appendStrBuffer(str.c_str());
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 15:58:10
 * 
 * 复制单字节到当前缓冲区中
 * @param byte 单字节
 */
void Buffer::appendByte(uint8_t byte) {
	this->_appendBuffer(this->bufferLength, &byte, 0, 1);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-14 15:24:27
 * 
 * 在当前缓冲区中插入字节
 * @param insertIndex 插入位置
 * @param buffer 字节数组指针
 * @param offset 偏移位置
 * @param length 复制长度
 * 
 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
 */
void Buffer::insertBuffer(uint32_t insertIndex, const uint8_t* buffer, uint32_t offset, uint32_t length) {
	this->_appendBuffer(insertIndex, buffer, offset, length);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-14 15:25:13
 * 
 * 在当前缓冲区中插入字节
 * @param insertIndex 插入位置
 * @param buffer 字节缓冲区
 * @param offset 偏移位置
 * @param length 复制长度，0 表示复制到末尾
 * 
 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
 */
void Buffer::insertBuffer(uint32_t insertIndex, const Buffer* buffer, uint32_t offset, uint32_t length) {
	if(offset >= buffer->bufferLength) {
		throw std::string("Not enough bytes can be copied!");
	}
	uint32_t realLength = 0;
	if(length != 0) {
		if(offset + length > buffer->bufferLength) {
			throw std::string("Not enough bytes can be copied!");
		}
		realLength = length;
	} else {
		realLength = buffer->bufferLength - offset;
	}

	this->insertBuffer(insertIndex, buffer->buffer, offset, realLength);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 15:58:10
 * 
 * 在当前缓冲区中插入单字节
 * @param insertIndex 插入位置
 * @param byte 单字节
 * 
 * @note 如果插入位置超过当前字节长度，那么缓存字节长度会变更到插入之后的字节尾部，中间间隔部分会填充 0
 */
void Buffer::appendByte(uint32_t insertIndex, uint8_t byte) {
	_appendBuffer(insertIndex, &byte, 0, 1);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-12 17:05:13
 * 
 * 将打印的字符串添加到当前缓冲区中
 * @param fmt 格式化字符串
 * @param ... 变长参数，用于填充格式化字符串参数
 */
void Buffer::appendPrint(const char * fmt, ...) {
	va_list va;
	va_start(va, fmt);
	this->appendVPrint(fmt, va);
	va_end(va);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-12 17:05:13
 * 
 * 将打印的字符串添加到当前缓冲区中
 * @param fmt 格式化字符串
 * @param va 变长参数，用于填充格式化字符串参数
 */
void Buffer::appendVPrint(const char * fmt, va_list va) {
	va_list copyList;
	va_copy(copyList, va);
	uint32_t size = vsnprintf(nullptr, 0, fmt, copyList);
	va_end(copyList);
	uint8_t buffer[size + 1];
	vsnprintf((char*)buffer, size + 1, fmt, va);
	this->appendBuffer(buffer, 0, size);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-11 18:54:06
 * 
 * 从字节缓冲区中移除字节
 * @param offset 偏移位置
 * @param length 移除长度
 */
void Buffer::removeRange(uint32_t offset, uint32_t length) {
	if((offset == 0 && length == 0) || (offset == 0 && length >= this->bufferLength)) {
		this->reset();
		return;
	}

	if(offset >= this->bufferLength || offset < 0) {
		return;
	}

	uint32_t end = offset + length;
	if(end >= this->bufferLength) {
		end = this->bufferLength;
	}

	if(end == this->bufferLength || length == 0) {
		// 后面全部移除
		this->bufferLength = offset;
		if(this->readIdx > this->bufferLength) {
			this->readIdx = this->bufferLength;
		}
	} else {
		// 移除开头及中间部分
		::memmove(this->buffer + offset, this->buffer + end, this->bufferLength - end);
		this->bufferLength -= length;
		if(offset < this->readIdx && this->readIdx <= offset + length) {
			this->readIdx = offset;
		}
		else if(offset < this->readIdx) {
			this->readIdx -= length;	
		}
	}

}

/**
 * @Author: CimZzz
 * @Date: 2022-08-08 12:08:34
 * 
 * 从字节缓冲区尾部移除字节
 * 
 * @param length 移除长度
 */
void Buffer::removeLast(uint32_t length) {
	if(length >= this->bufferLength) {
		this->reset();
		return;
	}

	this->bufferLength -= length;
	if(this->readIdx >= this->bufferLength) {
		this->readIdx = this->bufferLength;
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:22:31
 * 
 * 克隆当前缓冲资源
 * @param offset 偏移位置
 * @param length 克隆长度，0 表示克隆到末尾
 */
uint8_t* Buffer::getBufferClone(uint32_t offset, uint32_t length) {
	if(offset >= this->bufferLength) {
		return nullptr;
	}

	uint32_t realLength = 0;
	if(length != 0) {
		if(offset + length > this->totalLength) {
			return nullptr;
		}
		realLength = length;
	} else {
		realLength = this->bufferLength - offset;
	}

	uint8_t* newBuffer = new uint8_t[realLength];
	memcpy(newBuffer, this->buffer + offset, realLength);
	return newBuffer;
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-07 17:04:45
 * 
 * 直接获取当前缓存区指针
 * @return 缓冲区指针
 */
uint8_t* Buffer::getBuffer() const {
	return this->buffer;
}

/**
 * @Author: CimZzz
 * @Date: 2022-08-03 16:02:41
 * 
 * 直接将当前缓存区作为字符指针返回
 * 
 * @return 缓冲区指针
 * 
 * @note 自行裁定当前缓冲区是否可以当做字符串指针返回
 */
const char* Buffer::getBufferAsChar() const {
	return (const char *) this->buffer;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-10 16:56:37
 * 
 * 确保当前缓冲区已申请内存长度
 * @param size 已申请内存长度
 */
bool Buffer::makeSureTotalLength(uint32_t size) {
	if(this->totalLength >= size) {
		return true;
	}
	
	uint32_t incLength = size - this->totalLength;
	incLength = incLength < BUFFER_MIN_INC_SIZE ? BUFFER_MIN_INC_SIZE : incLength;
	this->buffer = (uint8_t *)realloc(this->buffer, incLength + this->totalLength);
	this->totalLength += incLength;
	return true;
}


/**
 * @Author: CimZzz
 * @Date: 2022-02-15 17:18:36
 * 
 * 读取一个单字节
 * 
 * @return 单字节
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
int8_t Buffer::readByte() {
	if(this->readIdx >= this->bufferLength) {
		throw VLBufferException("read byte failed: out of range");
	}

	uint32_t idx = this->readIdx ++;
	return this->buffer[idx];
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:48:24
 * 
 * 读取整数
 * 
 * @param byteLength 字节长度, 默认整数为 4 字节, 可以按需指定字节长度
 * @param bigEndian 是否为大端字节序, 默认为是
 * 
 * @return 整数
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
long long Buffer::readInt(unsigned char byteLength, bool bigEndian) {
	if(this->readIdx + byteLength > this->bufferLength) {
		throw VLBufferException("read int failed: out of range");
	}
	if(byteLength > 8) {
		throw VLBufferException("read int failed: range must be in 1 - 8");
	}

	long long number = 0;

	if(bigEndian) {
		while(byteLength > 0) {
			number |= (long long)(this->buffer[readIdx ++]) << ((byteLength - 1) << 3);
			byteLength --;
		}
	} else {
		int idx = 0;
		while(byteLength > 0) {
			number |= (long long)(this->buffer[readIdx ++]) << ((idx ++) << 3);
			byteLength --;
		}
	}

	return number;
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:56:31
 * 
 * 读取浮点数
 * 
 * @param byteLength 字节长度, 默认整数为 4 字节, 可以按需指定字节长度
 * @param bigEndian 是否为大端字节序, 默认为是
 * 
 * @return 浮点数
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
float Buffer::readFloat(bool bigEndian) {
	if(this->readIdx + 4 > this->bufferLength) {
		throw VLBufferException("read float failed: out of range");
	}

	_vl_buffer_float bufferFloat;

	if(_vl_buffer_check_is_big_order() == bigEndian) {
		// 大端字节序
		bufferFloat.c[0] = this->buffer[readIdx ++];
		bufferFloat.c[1] = this->buffer[readIdx ++];
		bufferFloat.c[2] = this->buffer[readIdx ++];
		bufferFloat.c[3] = this->buffer[readIdx ++];
	} else {
		// 小端字节序
		bufferFloat.c[3] = this->buffer[readIdx ++];
		bufferFloat.c[2] = this->buffer[readIdx ++];
		bufferFloat.c[1] = this->buffer[readIdx ++];
		bufferFloat.c[0] = this->buffer[readIdx ++];
	}

	return bufferFloat.number;
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:56:31
 * 
 * 读取双精度浮点数
 * 
 * @param byteLength 字节长度, 默认整数为 4 字节, 可以按需指定字节长度
 * @param bigEndian 是否为大端字节序, 默认为是
 * 
 * @return 双精度浮点数
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
double Buffer::readDouble(bool bigEndian) {
	if(this->readIdx + 8 > this->bufferLength) {
		throw VLBufferException("read double failed: out of range");
	}

	_vl_buffer_double bufferDouble;

	if(_vl_buffer_check_is_big_order() == bigEndian) {
		// 大端字节序
		bufferDouble.c[0] = this->buffer[readIdx ++];
		bufferDouble.c[1] = this->buffer[readIdx ++];
		bufferDouble.c[2] = this->buffer[readIdx ++];
		bufferDouble.c[3] = this->buffer[readIdx ++];
		bufferDouble.c[4] = this->buffer[readIdx ++];
		bufferDouble.c[5] = this->buffer[readIdx ++];
		bufferDouble.c[6] = this->buffer[readIdx ++];
		bufferDouble.c[7] = this->buffer[readIdx ++];
	} else {
		// 小端字节序
		bufferDouble.c[7] = this->buffer[readIdx ++];
		bufferDouble.c[6] = this->buffer[readIdx ++];
		bufferDouble.c[5] = this->buffer[readIdx ++];
		bufferDouble.c[4] = this->buffer[readIdx ++];
		bufferDouble.c[3] = this->buffer[readIdx ++];
		bufferDouble.c[2] = this->buffer[readIdx ++];
		bufferDouble.c[1] = this->buffer[readIdx ++];
		bufferDouble.c[0] = this->buffer[readIdx ++];
	}

	return bufferDouble.number;
}



/**
 * @Author: CimZzz
 * @Date: 2022-07-29 11:42:43
 * 
 * 读取字符串
 * 
 * @param strLength 字符串长度
 * 
 * @return 字符串
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
std::shared_ptr<char> Buffer::readChars(unsigned int strLength) {
	if(this->readIdx + strLength > this->bufferLength) {
		throw VLBufferException("read string failed: out of range");
	}

	std::shared_ptr<char> cPtr(new char[strLength + 1]);

	::memcpy(cPtr.get(), this->buffer + this->readIdx, strLength);

	(cPtr.get())[strLength] = '\0';

	this->readIdx += strLength;

	return cPtr;
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:58:42
 * 
 * 读取字符串
 * 
 * @param strLength 字符串长度
 * 
 * @return 字符串
 * 
 * @attention 读取失败时会抛出 [VLBufferException] 异常
 */
std::string Buffer::readString(unsigned int strLength) {
	if(this->readIdx + strLength > this->bufferLength) {
		throw VLBufferException("read string failed: out of range");
	}

	char c[strLength + 1];

	::memcpy(c, this->buffer + this->readIdx, strLength);

	c[strLength] = '\0';

	this->readIdx += strLength;

	return std::string(c);
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-29 11:47:02
 * 
 * 匹配字符串, 直到发现相同串时返回
 * 
 * @param matchStr 待匹配子串
 * @param mode 匹配模式
 * 
 * @return 匹配后的字符串, 如果匹配失败, 则返回 nullptr
 * 
 * @note 使用 KMP 算法进行字符串匹配
 * @note 无论是否返回包含子串, 读取下标都会越过子串
 */
std::shared_ptr<char> Buffer::matchString(const char * matchStr, uint32_t mode) {
	BufferRange range = this->_matchString(matchStr, nullptr, mode);
	if(range.isValid) {
		std::shared_ptr<char> ptr = readChars(range.end - range.begin);

		if(range.skipCount != 0) {
			this->backward(range.skipCount);
		}

		return ptr;
	}
	return std::shared_ptr<char>(nullptr);
}




/**
 * @Author: CimZzz
 * @Date: 2022-08-01 17:43:14
 * 
 * 匹配字符串, 直到发现相同串时返回
 * 如果相同串是 notMatchStr 的子串, 则继续寻找
 * 
 * @param matchStr 待匹配子串
 * @param notMatchStr 不匹配子串
 * @param mode 匹配模式
 * 
 * @return 匹配后的字符串, 如果匹配失败, 则返回 nullptr
 * 
 * @note 使用 KMP 算法进行字符串匹配
 * @note 无论是否返回包含子串, 读取下标都会越过子串
 * @note 不匹配子串长度必须大于匹配子串
 */
std::shared_ptr<char> Buffer::matchString(const char * matchStr, const char * notMatchStr, uint32_t mode) {
	BufferRange range = this->_matchString(matchStr, notMatchStr, mode);
	if(range.isValid) {
		std::shared_ptr<char> ptr = readChars(range.end - range.begin);

		if(range.skipCount != 0) {
			this->backward(range.skipCount);
		}

		return ptr;
	}
	return std::shared_ptr<char>(nullptr);
}

/**
 * @Author: CimZzz
 * @Date: 2022-08-03 14:20:54
 * 
 * 匹配字符串并跳过
 * 
 * @param matchStr 匹配字符串
 * @param notMatchStr 不匹配字符串
 * @param mode 匹配模式
 * 
 * @note 使用 KMP 算法进行字符串匹配
 */
void Buffer::skipUntil(const char * matchStr, const char * notMatchStr, uint32_t mode) {
	BufferRange range = this->_matchString(matchStr, notMatchStr, mode);
	if(range.isValid) {
		this->seek(range.end + range.skipCount);
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-07-19 18:59:41
 * 
 * 写入字节
 * 
 * @param byte 字节
 */
void Buffer::writeByte(const uint8_t& byte) {
	this->appendByte(byte);
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 19:00:48
 * 
 * 写入整数
 * 
 * @param number 整数
 * @param byteLength 表示 N 字节整数, 默认为 4
 * @param bigEndian 是否为大端字节序写入
 */
void Buffer::writeInt(long long number, unsigned char byteLength, bool bigEndian) {
	if(byteLength > 8) {
		throw VLBufferException("byte length of int must be in 1 ~ 8");
	}
	uint8_t buf[byteLength];

	if(bigEndian) {
		for(int i = byteLength - 1 ; i >= 0 ; i --) {
			buf[i] = number & 0xFF;
			number >>= 8;
		}
	} else {
		for(int i = 0 ; i < byteLength ; i ++) {
			buf[i] = number & 0xFF;
			number >>= 8;
		}
	}
	this->appendBuffer(buf, 0, byteLength);
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 19:07:54
 * 
 * 写入浮点数
 * 
 * @param number 浮点数
 * @param bigEndian 是否为大端字节序写入
 */
void Buffer::writeFloat(float number, bool bigEndian) {
	_vl_buffer_float bufFloat;
	bufFloat.number = number;
	if(_vl_buffer_check_is_big_order() == bigEndian) {
		this->appendBuffer((uint8_t *) bufFloat.c, 0, 4);
	} else {
		char buf[4];
		buf[0] = bufFloat.c[3];
		buf[1] = bufFloat.c[2];
		buf[2] = bufFloat.c[1];
		buf[3] = bufFloat.c[0];
		this->appendBuffer((uint8_t *) buf, 0, 4);
	}
}

/**
 * @Author: CimZzz
 * @Date: 2022-07-19 19:07:54
 * 
 * 写入双精度浮点数
 * 
 * @param number 双精度浮点数
 * @param bigEndian 是否为大端字节序写入
 */
void Buffer::writeDouble(double number, bool bigEndian) {
	_vl_buffer_double bufDouble;
	bufDouble.number = number;
	if(_vl_buffer_check_is_big_order() == bigEndian) {
		this->appendBuffer((uint8_t *) bufDouble.c, 0, 8);
	} else {
		char buf[8];
		buf[0] = bufDouble.c[7];
		buf[1] = bufDouble.c[6];
		buf[2] = bufDouble.c[5];
		buf[3] = bufDouble.c[4];
		buf[4] = bufDouble.c[3];
		buf[5] = bufDouble.c[2];
		buf[6] = bufDouble.c[1];
		buf[7] = bufDouble.c[0];
		this->appendBuffer((uint8_t *) buf, 0, 8);
	}
}


/**
 * @Author: CimZzz
 * @Date: 2022-02-19 11:09:52
 * 
 * 向前方回滚 N 个字节
 * @param count 回滚字节数
 * @return 回滚成功返回 true
 */
bool Buffer::forward(int32_t count) {
	uint32_t wantIdx = this->readIdx - count;
	if(this->readIdx < 0) {
		return false;
	}

	this->readIdx = wantIdx;
	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-02-19 11:10:44
 * 
 * 向后方前进 N 个字节
 * @param count 前进字节数
 * @return 前进成功返回 true
 */
bool Buffer::backward(int32_t count) {
	uint32_t wantIdx = this->readIdx + count;
	if(this->readIdx >= this->bufferLength) {
		return false;
	}

	this->readIdx = wantIdx;
	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-02-19 11:11:16
 * 
 * 将读取下标设置到指定位置
 * @param position 指定位置
 * @return 设置成功返回 true
 */
bool Buffer::seek(int32_t position) {
	if(position >= this->bufferLength) {
		return false;
	}

	this->readIdx = position;
	return true;
}



/**
 * @Author: CimZzz
 * @Date: 2022-02-21 15:32:07
 * 
 * 丢弃已经读过的字节缓冲
 */
void Buffer::dropRead() {
	if(this->readIdx >= this->bufferLength) {
		reset();
		return;
	}

	this->removeRange(0, readIdx);
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-07 14:33:06
 * 
 * 添加指定字节到当前缓冲区指定位置中
 * @param currentOffset 当前字节缓冲区指定位置
 * @param buffer 字节数组指针
 * @param offset 偏移位置
 * @param length 转移长度
 */
void Buffer::_appendBuffer(uint32_t currentOffset, const uint8_t* buffer, uint32_t offset, uint32_t length) {
	if(buffer == nullptr) {
		return;
	}

	uint32_t incLength = 0;
	if(currentOffset >= this->totalLength) {
		incLength = length;
	}
	else if(currentOffset + length > this->totalLength) {
		incLength = currentOffset + length - this->totalLength;
	}

	if(incLength != 0) {
		incLength = incLength < BUFFER_MIN_INC_SIZE ? BUFFER_MIN_INC_SIZE : incLength;
		this->buffer = (uint8_t *)realloc(this->buffer, incLength + this->totalLength);
		this->totalLength += incLength;
	}

	memcpy(this->buffer + currentOffset, buffer + offset, length);
	if(currentOffset > this->bufferLength) {
		// 中间留白
		memset(this->buffer + this->bufferLength, 0, currentOffset - this->bufferLength);
	}
	this->bufferLength = currentOffset + length;
}


/**
 * @Author: CimZzz
 * @Date: 2022-08-01 19:13:52
 * 
 * 匹配字符串, 直到发现相同串时返回字节缓冲区的起始下标和终止下标
 * 
 * @param matchStr 待匹配子串
 * @param notMatchStr 不匹配子串
 * @param mode 匹配模式
 * 
 * @note 不匹配子串长度要大于待匹配子串的长度, 否则无法生效
 * @note 通过 [mode] 来设置匹配模式, 参见 [BufferMatchMode]
 */
BufferRange Buffer::_matchString(const char * matchStr, const char * notMatchStr, uint32_t mode) {
	if(this->readIdx >= this->bufferLength || matchStr == nullptr) {
		return BufferRange {
			.isValid = false,
			.begin = 0,
			.end = 0,
			.skipCount = 0
		};
	}

	bool containMatchStr = (mode & Buffer::BufferMatchMode::BMC_Include_Match) != 0;
	bool containEOF = (mode & Buffer::BufferMatchMode::BMC_Include_EOF) != 0;

	// 待匹配字符串长度
	int matchSize = std::strlen(matchStr);
	int notMatchSize = 0;
	if(notMatchStr != nullptr) {
		notMatchSize = std::strlen(notMatchStr);
	}
	if(notMatchSize != 0 && notMatchSize <= matchSize) {
		// 不匹配子串长度必须大于匹配子串
		notMatchStr = 0;
	}

	if(this->readIdx + matchSize > this->bufferLength) {
		return BufferRange {
			.isValid = false,
			.begin = 0,
			.end = 0,
			.skipCount = 0
		};
	}

	// Next Array
	int matchArr[matchSize];
	uint32_t beginIdx = 0;
	uint32_t endIdx = 0;
	int matchIdx = -1;

	// 初始化 MatchArr
	matchArr[0] = -1;
	for(int i = 0, k = -1, loopEnd = matchSize - 1; i < loopEnd ; ) {
		if (k == -1 || matchStr[i] == matchStr[k]) {
			i++;
			k++;
			matchArr[i] = (matchStr[i] == matchStr[k] ? matchArr[k] : k);
		}
		else {
			k = matchArr[k];
		}
	}
	
	beginIdx = this->readIdx;

	while(true) {
		for(matchIdx = -1 ; beginIdx < this->bufferLength && matchIdx < matchSize ; ) {
			if (matchIdx == -1 || this->buffer[beginIdx] == matchStr[matchIdx]) {
				beginIdx++;
				matchIdx++;
			}
			else {
				matchIdx = matchArr[matchIdx];
			}
		}

		if(matchIdx < matchSize) {
			if(containEOF) {
				return BufferRange {
					.isValid = true,
					.begin = this->readIdx,
					.end = this->bufferLength,
					.skipCount = 0
				};
			}

			return BufferRange {
				.isValid = false,
				.begin = 0,
				.end = 0,
				.skipCount = 0
			};
		}

		// 检查不匹配子串
		if(notMatchSize == 0) {
			break;
		}

		bool isMatchNotMatchStr = true;
		for(int i = notMatchSize - matchSize - 1, j = 0; i >= 0 ; i --, j ++) {
			int idx = beginIdx - matchSize - j - 1;
			if(idx < 0) {
				isMatchNotMatchStr = false;
				break;
			}

			if(this->buffer[idx] != notMatchStr[i]) {
				isMatchNotMatchStr = false;
				break;
			}
		}

		if(isMatchNotMatchStr) {
			beginIdx = beginIdx - matchSize + 1;
			continue;
		}

		break;
	}


	BufferRange range = {
		.isValid = true,
		.begin = this->readIdx,
		.end = containMatchStr ? beginIdx: beginIdx - matchSize,
		.skipCount = containMatchStr ? 0 : (uint32_t)matchSize
	};
	return range;
}